package com.qire.antsrouter;

import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.qire.antscore.common.AssertUtils;
import com.qire.antsrouter.card.Postcard;
import com.qire.antsrouter.card.PostcardFactory;
import com.qire.antsrouter.lifecycleHandler.ActivityManageHandler;


/**
 * 路由器，对外提供路由操作的入口。<br />
 * 是全局单例的，使用时请在{@link Application#onCreate Application.onCreate}中调用{@link AntsRouter#init(Application) init}进行初始化
 */
public class AntsRouter {

    public static final AntsRouter ROUTER = new AntsRouter();

    private static final String TAG = "AntsRouter";

    private Application application;
    private Handler handler = new Handler(Looper.getMainLooper());

    private AntsRouter() {}

    /**
     * 初始化路由相关辅助功能及映射表，如 路由表、拦截器表等。
     * @param application 应用实例
     */
    public static void init(Application application) {

        ROUTER.application = application;

        // 注册Activity管理器到application
        ActivityManageHandler.HANDLER.register(application);

        try {
            // 加载路由/拦截器表
            MappingCache.loadInfo(application);
            // 初始化拦截器
            MappingCache.init(application.getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "初始化失败!", e);
        }
    }

    // todo 这里应该避免这样暴露，在框架内部使用尽量使用依赖传递，以避免使用框架的人拿到app实体做些不好的事。
    /**
     * 返回当前 APP 的实例
     * @return
     */
    public Application application() {
        return application;
    }

    /**
     * 提取组别
     * @param path 目标别名路径
     * @return 组别名
     */
    private String extractGroup(String path) {
        if (AssertUtils.isEmpty(path) || !path.startsWith("/")) {
            throw new RuntimeException(path + " : 不能提取group.");
        }
        try {
            String defaultGroup = path.substring(1, path.indexOf("/", 1));
            if (AssertUtils.isEmpty(defaultGroup)) {
                throw new RuntimeException(path + " : 不能提取group.");
            } else {
                return defaultGroup;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 构建跳转卡，通过完整路径
     * @param path 包含组群的完整路径
     * @param <T> 返回的具体挑卡类型
     * @return 返回需要的卡片。
     */
    public <T extends Postcard> T buildCard(String path) {
        return (T) buildCard(path, extractGroup(path));
    }

    /**
     * 构建跳转卡，通过路径名和组群名
     * @param path  路径名
     * @param group 组群名
     * @param <T> 返回的具体挑卡类型
     * @return 返回需要的卡片。
     */
    public <T extends Postcard> T  buildCard(String path, String group) {
        if (AssertUtils.isEmpty(path) || AssertUtils.isEmpty(group)) {
            throw new RuntimeException("路由地址无效!");
        }
        return (T) PostcardFactory.build(MappingCache.findRouteMetaBy(path, group), handler);
    }

}
